package org.dandelion.papercheck.controller;

import org.dandelion.papercheck.annotation.AdminRequired;
import org.dandelion.papercheck.annotation.PassToken;
import org.dandelion.papercheck.annotation.UserLoginToken;
import org.dandelion.papercheck.dto.*;
import org.dandelion.papercheck.entity.User;
import org.dandelion.papercheck.service.UserService;
import org.dandelion.papercheck.util.JWTUtils;
import org.dandelion.papercheck.util.ValidateUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletRequest;
import java.util.List;

@SuppressWarnings("rawtypes")
@CrossOrigin
@RestController
public class UserController {
    private static final Logger logger = LoggerFactory.getLogger(UserController.class);
    private final UserService userService;


    @Autowired
    public UserController(UserService userService) {
        this.userService = userService;
    }

    @PassToken
    @RequestMapping(path = "/admin/login")
    public BaseResult adminLogin(@RequestParam("username") String username,
                                 @RequestParam("password") String password) {
        User user = userService.login(username, password);
        if (user == null) {
            return BaseResult.success(new LoginResult(false, ""));
        } else {
            String token = userService.generateJWT(user);
            if ("true".equals(JWTUtils.getAdminFromToken(token))) {
                return BaseResult.success(new LoginResult(true, userService.generateJWT(user)));
            } else {
                return BaseResult.illegalAuthority(new LoginResult(false, "非管理员账号"));
            }
        }
    }

    @AdminRequired
    @PassToken
    @RequestMapping(path = "/admin/users")
    public BaseResult adminUserList(@RequestParam(value = "size", required = false, defaultValue = "5") Integer size,
                                    @RequestParam(value = "page", required = false, defaultValue = "0") Integer page) {
        List<User> users = userService.getUserList(size, page);
        UserListResult userListResult = new UserListResult();

        for (User user : users) {
            userListResult.add(new UserDTO(user.getId(), user.getUsername(), user.getPhone(),
                    user.getIsVip(), user.getEmail()));
        }

        return BaseResult.success(userListResult);
    }

    @AdminRequired
    @RequestMapping(path = "/admin/setVIP")
    public BaseResult adminUserList(@RequestParam(value = "userId") String id,
                                    @RequestParam(value = "vip") Boolean vip) {

        Long userId = Long.valueOf(id);

        Boolean bool = userService.changeIsVip(userId, vip);
        return BaseResult.success(true);
    }

    @PassToken
    @RequestMapping(path = "/login")
    public BaseResult login(@RequestParam("username") String username,
                            @RequestParam("password") String password) {
        User user = userService.login(username, password);
        if (user == null) {
            return BaseResult.success(new LoginResult(false, ""));
        } else {
            return BaseResult.success(new LoginResult(true, userService.generateJWT(user)));
        }
    }

    @PassToken
    @RequestMapping(path = "/register")
    public BaseResult register(@RequestParam("username") String username,
                               @RequestParam("password") String password,
                               @RequestParam(value = "phone", required = false, defaultValue = "")
                                       String phone,
                               @RequestParam(value = "email", required = false, defaultValue = "")
                                       String email) {
        if (!"".equals(phone) && !ValidateUtil.validatePhone(phone)) {
            return BaseResult.error(600, "手机格式错误");
        }

        if (!"".equals(email) && !ValidateUtil.validateEmail(email)) {
            return BaseResult.error(601, "邮箱格式错误");
        }

        if (userService.checkUsernameDup(username)) {
            return BaseResult.error(700, "用户已存在");
        }

        User user = userService.register(username, password, phone, email);
        if (user == null) {
            return BaseResult.error(701, "密码验证错误");
        } else {
            return BaseResult.success(new LoginResult(true, userService.generateJWT(user)));
        }
    }

    @PassToken
    @RequestMapping(path = "/checkUsername")
    public BaseResult checkUsername(@RequestParam("username") String username) {
        Boolean bool = userService.checkUsernameDup(username);
        return BaseResult.success(new DuplicationResult(bool));
    }

    @PassToken
    @RequestMapping(path = "/logout")
    public BaseResult logout() {
        return BaseResult.logout();
    }


    @PassToken
    @RequestMapping(path = "/JwtError")
    public BaseResult JwtError() {
        return BaseResult.JwtError();
    }

    @PassToken
    @RequestMapping(path = "/illegalAuthority")
    public BaseResult illegalAuthority() {
        return BaseResult.illegalAuthority();
    }

    @UserLoginToken
    @RequestMapping(path = "/resetPwd")
    public BaseResult resetPwd(HttpServletRequest httpServletRequest,
                               @RequestParam("oldPassword") String oldPassword,
                               @RequestParam("newPassword") String newPassword) {
        String name = JWTUtils.getNameFromRequest(httpServletRequest);
        User user = userService.login(name, oldPassword);
        if (user == null) {
            return BaseResult.success(new LoginResult(false, "密码错误"));
        } else {
            user = userService.resetPwd(user, newPassword);
            if (user != null) {
                return BaseResult.success(new LoginResult(true, "修改密码成功"));
            } else {
                return BaseResult.success(new LoginResult(false, "修改密码失败"));
            }
        }
    }
}
